<?php

namespace app\service\impl;

use app\enum\MessageConstant;
use app\popo\dto\AddressBookDTO;
use app\popo\model\AddressBook;
use app\repository\AddressBookRepository;
use app\service\AddressBookService;
use app\support\JwtHelper;
use DI\Attribute\Inject;
use support\exception\BusinessException;

class AddressBookServiceImpl implements AddressBookService
{
    #[Inject]
    protected AddressBookRepository $addressBookRepository;

    /**
     * 查询当前登录用户的所有地址信息
     * @param AddressBook $addressBook
     * @return array
     */
    public function list(AddressBook $addressBook): array
    {
        $conditions = [];
        
        if ($addressBook->user_id !== null) {
            $conditions['user_id'] = $addressBook->user_id;
        }
        
        if ($addressBook->is_default !== null) {
            $conditions['is_default'] = $addressBook->is_default;
        }

        return $this->addressBookRepository->list($conditions);
    }

    /**
     * 新增地址
     * @param AddressBookDTO $addressBookDTO
     * @return void
     */
    public function save(AddressBookDTO $addressBookDTO): void
    {
        $userId = user_id();
        
        $data = $addressBookDTO->toArray();
        $data['user_id'] = $userId;
        
        // 如果设置为默认地址，先清除其他默认地址
        if ($addressBookDTO->getIsDefault() === 1) {
            $this->addressBookRepository->clearDefaultByUserId($userId);
        }
        
        $this->addressBookRepository->save($data);
    }

    /**
     * 根据id查询地址
     * @param int $id
     * @return array
     */
    public function getById(int $id): array
    {
        $userId = user_id();
        
        // 检查地址是否属于当前用户
        if (!$this->addressBookRepository->belongsToUser($id, $userId)) {
            throw new BusinessException("无权访问该地址");
        }

        $addressBook = $this->addressBookRepository->getById($id);

        return $this->addressBookRepository->format($addressBook);
    }

    /**
     * 根据id修改地址
     * @param AddressBookDTO $addressBookDTO
     * @return void
     * @throws BusinessException
     */
    public function update(AddressBookDTO $addressBookDTO): void
    {
        $userId = user_id();
        $id = $addressBookDTO->getId();
        
        if (!$id) {
            throw new BusinessException("地址ID不能为空");
        }
        
        // 检查地址是否属于当前用户
        if (!$this->addressBookRepository->belongsToUser($id, $userId)) {
            throw new BusinessException("无权修改该地址");
        }
        
        $addressBook = $this->addressBookRepository->getById($id);
        if (!$addressBook) {
            throw new BusinessException("地址不存在");
        }
        
        // 如果设置为默认地址，先清除其他默认地址
        if ($addressBookDTO->getIsDefault() === 1) {
            $this->addressBookRepository->clearDefaultByUserId($userId);
        }
        
        $data = $addressBookDTO->toArray();
        unset($data['id']); // 移除ID字段
        
        $this->addressBookRepository->update($addressBook, $data);
    }

    /**
     * 设置默认地址
     * @param $id
     * @return void
     */
    public function setDefault($id): void
    {
        $userId = user_id();
        
        if (!$id) {
            throw new BusinessException("地址ID不能为空");
        }
        
        // 检查地址是否属于当前用户
        if (!$this->addressBookRepository->belongsToUser($id, $userId)) {
            throw new BusinessException("无权操作该地址");
        }
        
        $addressBook = $this->addressBookRepository->getById($id);
        if (!$addressBook) {
            throw new BusinessException("地址不存在");
        }
        
        // 先清除其他默认地址
        $this->addressBookRepository->clearDefaultByUserId($userId);
        
        // 设置当前地址为默认
        $this->addressBookRepository->setAsDefault($addressBook);
    }

    /**
     * 根据id删除地址
     * @param int $id
     * @return void
     * @throws BusinessException
     */
    public function deleteById(int $id): void
    {
        $userId = user_id();
        
        // 检查地址是否属于当前用户
        if (!$this->addressBookRepository->belongsToUser($id, $userId)) {
            throw new BusinessException("无权删除该地址");
        }
        
        $addressBook = $this->addressBookRepository->getById($id);
        if (!$addressBook) {
            throw new BusinessException("地址不存在");
        }
        
        $this->addressBookRepository->delete($addressBook);
    }
}